package com.monitor.common;

import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.log.Logger;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.render.ViewType;
import com.monitor.controller.IndexController;
import com.monitor.controller.ManagerController;
import com.monitor.exception.MonitorException;
import com.monitor.exception.TimeOutException;
import com.monitor.model.Admin;
import com.monitor.model.Log;
import com.monitor.model.Person;
import com.monitor.model.Record;
import com.monitor.model.Sensor;
import com.monitor.service.Alarm;
import com.monitor.service.CleanDatabaseThread;
import com.monitor.service.MonitorServerSocket;
import com.monitor.utils.DateUtil;

public class MonitorConfig extends JFinalConfig {
	private static Logger logger = Logger.getLogger(MonitorConfig.class);

	/*
	 * 配置常量
	 */
	@Override
	public void configConstant(Constants constants) {
		loadPropertyFile("config.properties");
		constants.setDevMode(getPropertyToBoolean("devMode", false));
		constants.setViewType(ViewType.FREE_MARKER);
	}

	@Override
	public void configHandler(Handlers handlers) {

		DruidStatViewHandler dvh = new DruidStatViewHandler("/druid");
		handlers.add(dvh);
	}

	@Override
	public void configInterceptor(Interceptors arg0) {
		// TODO Auto-generated method stub

	}

	/*
	 * 配置插件
	 */
	@Override
	public void configPlugin(Plugins plugins) {
		DruidPlugin druid = new DruidPlugin(getProperty("jdbcUrl"),
				getProperty("user"), getProperty("password"));
		druid.addFilter(new StatFilter());
		WallFilter wall = new WallFilter();
		wall.setDbType("mysql");
		druid.addFilter(wall);
		plugins.add(druid);
		ActiveRecordPlugin arp = new ActiveRecordPlugin(druid);

		plugins.add(arp);
		// 接下来做表的映射
		arp.addMapping("sensor", Sensor.class);
		arp.addMapping("person", Person.class);
		arp.addMapping("record", Record.class);
		arp.addMapping("admin", Admin.class);
		arp.addMapping("log", Log.class);

	}

	/*
	 * 路由配置 这里尝试使用注解的路由方式 模仿springMVC
	 */
	@Override
	public void configRoute(Routes routes) {
		routes.add("/index", IndexController.class);
		routes.add("/m", ManagerController.class);
	}

	@Override
	public void afterJFinalStart() {
		ScheduledExecutorService executorClean = Executors.newSingleThreadScheduledExecutor();
		ExecutorService executorSocket = Executors.newSingleThreadExecutor();
		//启动一个定时清理的线程
	//	executorClean.scheduleWithFixedDelay(new CleanDatabaseThread(), 30, 30, TimeUnit.DAYS);
		executorClean.execute(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				MonitorServerSocket monitor = new MonitorServerSocket(
						getPropertyToInt("port"),
						getPropertyToInt("normalTemperature"),
						getPropertyToInt("normalHumidity"),
						getPropertyToInt("interval")
						);
				boolean serverOn = true;
				while (serverOn) {
					try {
						
						Socket socket = monitor.accrept();
						logger.info("已连接");
						try {
							monitor.getRecord(socket);
						} catch (TimeOutException e) {
							// 读取超时 客户端关闭
							logger.error("读取超时 客户端关闭");
							try {
								monitor.close();
							} catch (IOException e1) {
								// socket关闭失败
								logger.error("socket关闭失败");
								throw new MonitorException("ServerSocket关闭失败");
							}

						}
					} catch (MonitorException e) {
						//TODO 不可处理的异常，通知管理员重启服务器
						logger.error("不可处理的异常，通知管理员重启服务器");
						logger.error(e.getMessage());
						e.printStackTrace();
						try {
							monitor.close();
							Alarm.sendMessage(3292, "#datatime#="+DateUtil.getDateNow());
						} catch (IOException e1) {
							// socket关闭失败
							logger.error("socket关闭失败");
							e1.printStackTrace();
						}
						
					}
				}
			}
		});
		
		
		
		
	}

	@Override
	public void beforeJFinalStop() {

	};
}
